<?php
// +----------------------------------------------------------------------
// | CSMITSM  [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2024 https://www.fastadmin.net All rights reserved.
// +----------------------------------------------------------------------
// | Author: chenshiming
// +----------------------------------------------------------------------

namespace app\admin\controller\csmitsm;

use addons\csmitsm\library\sdnode\xstack\utils\XsJsonUtils;
use think\Db;
use addons\csmitsm\library\xcore\xcore\base\XcABackend;
use addons\csmitsm\library\xcore\xcore\utils\XcDaoUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcConfigUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcRequestUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcAdminTabUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcDatabaseUtils;
use addons\csmitsm\library\xcore\xcflow\utils\XcformDataUtils;
use addons\csmitsm\library\xcore\xcflow\utils\XcflowToMdmUtils;
use addons\csmitsm\library\xcore\xcflow\utils\XcformFieldsUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcRequestPathUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcTransactionUtils;

/**
 * 流程
 *
 * @icon fa fa-circle-o
 */
class Xcflow extends XcABackend
{

   /**
    * Xcflow模型对象
    * @var \app\admin\model\csmitsm\Xcflow
    */
   protected $model = null;

   public function _initialize()
   {
      parent::_initialize();
      $this->model = new \app\admin\model\csmitsm\Xcflow;
      $this->assign("xcformtypeList", $this->model->getXcformtypeList());
      $this->assign("haspublishList", $this->model->getHaspublishList());
      $this->assign("statusList", $this->model->getStatusList());
      $this->assign("mdmtabletypeList", $this->model->getMdmtabletypeList());

      // csmitsm:设置页面tabs
      $xc_tabid = XcRequestUtils::param(["ids", "id", "xc_tabid"]);
      if (!empty($xc_tabid)) {
         $row = XcDaoUtils::getRowById($this->model, $xc_tabid);
         $this->assignconfig("xc_tabid", $xc_tabid);
         XcAdminTabUtils::append_control_initialize('xc' . $row->xcformtype, $xc_tabid, __CLASS__, $this->view);
      }
   }

   public function index()
   {
      //设置过滤方法
      $this->request->filter(['strip_tags', 'trim']);
      if (false === $this->request->isAjax()) {
         return $this->view->fetch();
      }
      //如果发送的来源是 Selectpage，则转发到 Selectpage
      if ($this->request->request('keyField')) {
         return $this->selectpage();
      }
      [$where, $sort, $order, $offset, $limit] = $this->buildparams();

      $list = $this->model
         ->where($where)
         ->where('status', '=', 'normal')
         ->order($sort, $order)
         ->paginate($limit);

      XcDaoUtils::bindDbListColumn($list, "xcflow_group_id", new \app\admin\model\csmitsm\XcflowGroup(), "xcflow_group", ["name"]);

      $result = ['total' => $list->total(), 'rows' => $list->items()];
      return json($result);
   }

   protected function beforeAddPage()
   {
      $xcformtype = XcRequestUtils::get("xcformtype", true);
      $this->view->assign("xcformtype", $xcformtype);
   }

   /**
    * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
    * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
    * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
    */

   public function fieldconfig($ids)
   {
      $addoncode = XcConfigUtils::getAddonCode();
      // $xcbaseurl = XcConfigUtils::config("xcbaseurl") . "/addons/{$addoncode}/xc_flow/";
      $xcbaseurl = XcRequestPathUtils::urlAddons("/xc_flow/");
      $param = ["xcform_id" => $ids, "xccontrol" => "xcform", "xcbaseurl" => $xcbaseurl];

      $url = XcRequestUtils::appendUrlParams("/assets/addons/{$addoncode}/h5_xcflow_xcform/#/", $param);
      $xdebugSrc = XcRequestUtils::appendUrlParams("http://localhost:8080/#/", $param);

      return $this->fetchIframePage($url, $xdebugSrc);
   }

   public function statusconfig($ids)
   {
      $addoncode = XcConfigUtils::getAddonCode();
      // $xcbaseurl = XcConfigUtils::config("xcbaseurl") . "/addons/";
      $xcbaseurl = XcRequestPathUtils::urlBase("/addons/");
      $param = ["xcform_id" => $ids, "xcbaseurl" => $xcbaseurl];

      $url = XcRequestUtils::appendUrlParams("/assets/addons/{$addoncode}/h5_pc_console/#/", $param);
      $xdebugSrc = XcRequestUtils::appendUrlParams("http://localhost:5173/#/", $param);

      return $this->fetchIframePage($url, $xdebugSrc);
   }

   private function _mdmconfigSubmit($row)
   {
      $params = $this->request->post('row/a');

      XcTransactionUtils::service(function () use ($params, $row) {
         $mdmfieldjson = null;
         switch ($params['mdmtabletype']) {
            case "create_table":
               $mdmtablename = isset($params['createmdmtablename']) ? $params['createmdmtablename'] : $params['mdmtablename'];
               // XcflowToMdmUtils::createOrUpdateMdmTable($row, $mdmtablename, $row['name']);
               // $xcfieldjsonObj = json_decode($row['xcfieldjson'], true);
               $xcfieldjsonObj = XsJsonUtils::stringToJson($row['xcfieldjson']);
               XcformDataUtils::createOrUpdateTable($mdmtablename, $row["name"], $xcfieldjsonObj);
               $mdmfieldjson = XsJsonUtils::jsonToString(XcflowToMdmUtils::generateCreateTableMdmfieldjsonFromXcflowTable($row));
               break;
            case "select_table";
               $mdmtablename = isset($params['selectmdmtablename']) ? $params['selectmdmtablename'] : $params['mdmtablename'];
               $mdmfieldjson = $params['mdmfieldjson'];
               break;
         }

         $row->save([
            'mdmtabletype' => $params['mdmtabletype'],
            'mdmtablename' => $mdmtablename,
            'mdmfieldjson' => $mdmfieldjson,
         ]);
      });

      $this->success();
   }


   public function mdmconfig($ids)
   {
      $row = XcDaoUtils::getRowById($this->model, $ids);

      if ($this->request->isAjax()) {
         $this->_mdmconfigSubmit($row);
      }

      // fill fieldjson
      if (true) {
         // $mdmfieldjson = json_decode($row->mdmfieldjson, true);
         // $mdmfieldjson = empty($mdmfieldjson) ? [] : $mdmfieldjson;
         $mdmfieldjson = XsJsonUtils::stringToJson($row->mdmfieldjson);

         // $xcfieldjsonObj = json_decode($row->xcfieldjson, true);
         $xcfieldjsonObj = XsJsonUtils::stringToJson($row->xcfieldjson);
         if ($xcfieldjsonObj != null) {
            foreach ($xcfieldjsonObj as $field) {
               $isFound = false;
               foreach ($mdmfieldjson as $mdmfield) {

                  if ($field['fieldcode'] == $mdmfield['flowfieldcode']) {
                     $isFound = true;
                     break;
                  }
               }

               if (!$isFound) {
                  $mdmfieldjson[] = [
                     'flowfieldcode' => $field['fieldcode'],
                     'mdmfieldcode' => '',
                     'pk' => 0,
                     'status' => 1
                  ];
               }
            }
         }
         $row->mdmfieldjson = XsJsonUtils::jsonToString($mdmfieldjson);
      }

      if (true) {
         $row->selectmdmtablename = $row->mdmtablename;
         $code = $row->code;
         $row->createmdmtablename = empty($row->mdmtablename) ? XcDatabaseUtils::appendTablePrefix(XcConfigUtils::getAddonCode() . "_mdm_" . $code) : $row->mdmtablename;
      }

      $this->assign("row", $row);
      return $this->fetch();
   }

   public function selectTables()
   {
      $displayname = XcRequestUtils::get("displayname");
      $list = XcDatabaseUtils::queryTableList($displayname);
      return json(['list' => $list, 'total' => count($list)]);
   }

   public function selectTablefields()
   {
      $displayname = XcRequestUtils::get("displayname");
      $name = XcRequestUtils::get("keyValue");

      $tablenameParam = XcRequestUtils::getBuildCustomParams("tablename");
      $list = XcDatabaseUtils::queryTablefieldList($tablenameParam[2], $displayname);

      $list2 = [];
      if (!empty($name)) {
         foreach ($list as $item) {
            if ($item['name'] == $name) {
               $list2[] = $item;
            }
         }
      } else {
         $list2 = $list;
      }

      return json(['list' => $list2, 'total' => count($list2)]);
   }



   protected function afterAddSubmit($model)
   {
      $code = strtolower($model['code']);
      $name = strtolower($model['name']);
      XcDatabaseUtils::assertValidateTablename($code, $name);

      // assert code unique 
      if (true) {
         $row = XcDaoUtils::getRowBySql(new \app\admin\model\csmitsm\Xcflow(), [
            ['code', '=', $code],
            ['id', "<>", $model->id]
         ]);
         if ($row) {
            $this->error("编码重复,请更换编码:" . $code);
         }
      }
      // init database flowtable
      $prefix = ($model['xcformtype'] == 'flowsub') ? "flowsub" : "flow";
      $tablename = XcDatabaseUtils::appendTablePrefix(XcConfigUtils::getAddonCode() . "_{$prefix}_" . $code);
      XcformDataUtils::createOrUpdateTable($tablename, $name, null);

      // fieldjsons -> fa_csmitsm_xcflowfield json
      $xcfieldjsonObj = [];
      if ($model['xcformtype'] == 'flow') {
         // $staticFieldsJsonObj = json_decode(XcConfigUtils::xpconfig("xcflow.xcflow.staticFieldsJsonString"), true);
         $staticFieldsJsonObj = XsJsonUtils::stringToJson(XcConfigUtils::xpconfig("xcflow.xcflow.staticFieldsJsonString"));
         foreach ($staticFieldsJsonObj as $index => $field) {
            // $item = json_decode($field['fieldjson'], true);
            $item = XsJsonUtils::stringToJson($field['fieldjson']);

            $fieldtitle = isset($item['xcform_base_xctitle']['value']) ? $item['xcform_base_xctitle']['value'] : "";
            $fieldcode = isset($item['xcform_base_inputfieldcode']['value']) ? $item['xcform_base_inputfieldcode']['value'] : "";
            $item['__vModel__'] = 'field10' . ($index + 1);
            $field = [
               'title' => $fieldtitle,
               'fieldjson' => XsJsonUtils::jsonToString($item),
               'fieldcode' => $fieldcode,
               'fieldtag' => $item['__config__']['tag'],
            ];
            $xcfieldjsonObj[] = $field;

            // create table_column
            if (!empty($fieldcode)) {
               $fieldInstance = XcformFieldsUtils::createFieldInstance("xcform", $field);
               $columnType = $fieldInstance->getDbfieldColumnType();
               XcDatabaseUtils::alertTableField('add_column', $tablename, $fieldcode, $columnType, $fieldtitle);
            }

            XcDaoUtils::create(new \app\admin\model\csmitsm\Xcflowfield(), [
               "xcflow_id" => $model->id,
               "vmodel" => $item['__vModel__'],
               "title" => $field['title'],
               "fieldjson" => $field['fieldjson'],
               "fieldtag" => $field['fieldtag'],
               "haspublish" => "Y",
               "weigh" => 0,
            ]);
         }
      }
      $model->save([
         "code" => $code,
         "name" => $name,
         "haspublish" => "Y",
         "publishtablename" => $tablename,
         "xcflowjson" => XcConfigUtils::xpconfig("xcflow.xcflow.staticXcflowJsonString"),
         "xcfieldjson" => XsJsonUtils::jsonToString($xcfieldjsonObj)
      ]);
   }


   protected function afterEditSubmit($row)
   {
      Db::execute("ALTER TABLE {$row->publishtablename} COMMENT '{$row->name}'");
   }

   protected function afterDelSubmit($row)
   {
      $publishtablename = $row->publishtablename;
      $deleted_publishtablename = "deleted_{$publishtablename}_{$row->id}";
      Db::execute("RENAME TABLE {$publishtablename} TO {$deleted_publishtablename};");

      $mdmtablename = $tablename = $row->mdmtablename;
      $deleted_mdmtablename = "deleted_{$mdmtablename}_{$row->id}";
      if ($row->mdmtabletype == 'create_table' && !empty($row->mdmtablename)) {
         Db::execute("RENAME TABLE {$mdmtablename} TO {$deleted_mdmtablename};");
      }

      $row->save([
         'publishtablename' => $deleted_publishtablename,
         'mdmtablename' => $deleted_mdmtablename
      ]);
   }
}
